package com.hqd.ch03.v6.reader.xml.parse.spport;

import com.hqd.ch03.v6.config.BeanDefinition;
import com.hqd.ch03.v6.config.MutablePropertyValues;
import com.hqd.ch03.v6.reader.xml.parse.BeanDefinitionDocumentReader;
import com.hqd.ch03.v6.registry.BeanDefinitionRegistry;
import org.apache.commons.lang3.StringUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class DefaultBeanDefinitionDocumentReader implements BeanDefinitionDocumentReader {

    public static final String DESCRIPTION_ELEMENT = "description";
    public static final String NAME_ATTRIBUTE = "name";
    public static final String BEAN_ELEMENT = "bean";
    public static final String ID_ATTRIBUTE = "id";
    public static final String CLASS_ATTRIBUTE = "class";
    public static final String SCOPE_ATTRIBUTE = "scope";
    public static final String LAZY_INIT_ATTRIBUTE = "lazy-init";
    public static final String INIT_METHOD_ATTRIBUTE = "init-method";
    public static final String DESTROY_METHOD_ATTRIBUTE = "destroy-method";
    public static final String FACTORY_METHOD_ATTRIBUTE = "factory-method";
    public static final String FACTORY_BEAN_ATTRIBUTE = "factory-bean";
    public static final String REF_ATTRIBUTE = "ref";
    public static final String VALUE_ATTRIBUTE = "value";
    private static final String SINGLETON_ATTRIBUTE = "singleton";


    @Override
    public void registerBeanDefinitions(Document doc, BeanDefinitionRegistry registry) {
        parseBeanDefinitions(doc.getDocumentElement(), registry);
    }

    protected void parseBeanDefinitions(Element root, BeanDefinitionRegistry registry) {
        NodeList nl = root.getChildNodes();
        for (int i = 0; i < nl.getLength(); i++) {
            Node node = nl.item(i);
            if (node instanceof Element) {
                Element ele = (Element) node;
                processBeanDefinition(ele, registry);
            }
        }
    }

    private void processBeanDefinition(Element ele, BeanDefinitionRegistry registry) {
        BeanDefinition bd = new BeanDefinition();
        String id = ele.getAttribute(ID_ATTRIBUTE);
        bd.setId(id);
        bd.setScope(ele.getAttribute(SCOPE_ATTRIBUTE));
        String lazyInit = ele.getAttribute(LAZY_INIT_ATTRIBUTE);
        bd.setLazyInit(StringUtils.isBlank(lazyInit) ? true : Boolean.valueOf(lazyInit));
        bd.setBeanClass(ele.getAttribute(CLASS_ATTRIBUTE));
        bd.setProperties(parsePropertyElements(ele.getChildNodes()));
        registry.registerBeanDefinition(bd.getId(), bd);
    }

    /**
     * 转换bean下的property节点
     *
     * @param nodes
     * @return
     */
    private MutablePropertyValues parsePropertyElements(NodeList nodes) {
        MutablePropertyValues propertyValues = new MutablePropertyValues();
        if (nodes.getLength() != 0) {
            for (int i = 0; i < nodes.getLength(); i++) {
                Node node = nodes.item(i);
                if (node instanceof Element) {
                    Element element = (Element) node;
                    propertyValues.addProperty(element.getAttribute(NAME_ATTRIBUTE), element.getAttribute(VALUE_ATTRIBUTE));
                }
            }
        }
        return propertyValues;
    }

}
